/**
 * A distance joint constrains two points on two bodies
 * to remain at a fixed distance from each other. You can view
 * this as a massless, rigid rod.
**/
public class b2DistanceJoint extends b2Joint {

	// mock fields
	float m_length;
	float m_frequencyHz;
	float m_dampingRatio;
	b2Vec2 m_localAnchorA;
	b2Vec2 m_localAnchorB;

	public b2DistanceJoint(int addr) {
		super(addr);

		m_localAnchorA = new b2Vec2(jniLocalAnchorA(addr));
		m_localAnchorB = new b2Vec2(jniLocalAnchorB(addr));
	}

	@Override
	public void release() {
		if ( address != 0 ) {
			m_localAnchorA.address = 0;
			m_localAnchorB.address = 0;
			super.release();
		}
	}

	/**Remember to call release() on the returned b2Vec2*/
	public b2Vec2 GetAnchorA() {
		return m_bodyA.GetWorldPoint(m_localAnchorA);
	}

	/**Remember to call release() on the returned b2Vec2*/
	public b2Vec2 GetAnchorB() {
		return m_bodyB.GetWorldPoint(m_localAnchorB);
	}

	/**
	 * Get the reaction force given the inverse time step.
	 * Unit is N.
	 * NOte: remember to call release()
	**/
	public b2Vec2 GetReactionForce(float inv_dt) {
		return new b2Vec2(jniGetReactionForce(address, inv_dt));
	}

	/**
	 * Get the reaction torque given the inverse time step.
	 * Unit is N*m. This is always zero for a distance joint.
	 * Note: Currently not used(in Box2D), so I just return 0.
	*/
	public float GetReactionTorque(float inv_dt) {
		return 0.0f;
	}

	/**
	 * The local anchor point relative to bodyA's origin.
	 * Note: don't call release() on the returned b2Vec2
	**/
	public b2Vec2 GetLocalAnchorA() {
		return m_localAnchorA;
	}

	/**
	 * The local anchor point relative to bodyB's origin.
	 * Note: don't call release() on the returned b2Vec2
	**/
	public b2Vec2 GetLocalAnchorB() {
		return m_localAnchorB;
	}

	/**
	 * Set the natural length.
	 * Manipulating the length can lead to non-physical behavior when the frequency is zero.
	**/
	public void SetLength(float length) {
		jniSetLength(address, length);
		m_length = length;
	}

	/**Get the natural length.*/
	public float GetLength() {
		return m_length;
	}

	/**Set frequency in Hz.*/
	public void SetFrequency(float hz) {
		jniSetFrequency(address, hz);
		m_frequencyHz = hz;
	}

	/**Get frequency in Hz.*/
	public float GetFrequency() {
		return m_frequencyHz;
	}
	
	/**Set damping ratio.*/
	public void SetDampingRatio(float ratio) {
		jniSetDampingRatio(address, ratio);
		m_dampingRatio = ratio;
	}

	/**Get damping ratio.*/
	public float GetDampingRatio() {
		return m_dampingRatio;
	}


	private static native int jniLocalAnchorA(int me);
	private static native int jniLocalAnchorB(int me);
	private static native void jniSetLength(int me, float length);
	private static native void jniSetFrequency(int me, float hz);
	private static native void jniSetDampingRatio(int me, float ratio);
	private static native int jniGetReactionForce(int me, float inv_dt);

}
